package com.tianzehua.jvm.classloader;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;

/**
 * 自定义类加载器测试
 * @author tianzehua
 * @date 2019/03/31
 */
public class MyTest12 extends ClassLoader{

    private String classLoaderName;

    public String path;

    public void setPath(String path) {
        this.path = path;
    }

    private MyTest12(String classLoaderName){
        /* 将系统类加载器当做该类加载器的父加载器 */
        super();
        this.classLoaderName = classLoaderName;
    }

    public MyTest12(String classLoaderName,ClassLoader parent){
        /* 显式指定该类加载器的父加载器 */
        super(parent);
        this.classLoaderName = classLoaderName;
    }

    @Override
    protected Class<?> findClass(String className) {
        /* findClass方法会被loadclass方法调用，作用是用来绑定我们要加载的类的class，需要我们重写父类的方法来自定义相应的规则*/
        byte[] data = this.loadClassData(className);
        /* 委托defineClass方法来生成class，将二进制文件转化为class实例 */
        return defineClass(className,data,0, data.length);
    }

    private byte[] loadClassData(String className){
        /* 根据输入的名字，来找到相应的文件，并且以字节数组返回相应的信息 */
        System.out.println("loadclassdata invoke");
        InputStream inputStream = null;
        byte[] data = null;
        ByteArrayOutputStream byteArray =  null;

        try {
             this.classLoaderName = this.classLoaderName.replace(".","\\");
            className = className.replace(".","\\");
            String fileExtension = ".class";
            inputStream  = new FileInputStream(new File(this.path + className + fileExtension));
             byteArray = new ByteArrayOutputStream();
             int ch;
             while (-1 != (ch = inputStream.read())){
                 byteArray.write(ch);
             }
             data = byteArray.toByteArray();
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            try {
                inputStream.close();
                byteArray.close();
            }catch (Exception e){
                e.printStackTrace();
            }
        }
        return data;
    }

    public static void main(String[] args) throws  Exception {
        MyTest12  myTest12 = new MyTest12("loader1");
        myTest12.setPath("E:\\");
        Class<?> clazz = myTest12.loadClass("com.tianzehua.jvm.classloader.MyTest1");
        Object object = clazz.newInstance();
        System.out.println(clazz.hashCode());
        System.out.println(object);
        System.out.println("-----------------------------------");

        MyTest12  myTest122 = new MyTest12("loader2",myTest12);
        myTest122.setPath("E:\\");
        Class<?> clazz2 = myTest122.loadClass("com.tianzehua.jvm.classloader.MyTest1");
        Object object2 = clazz2.newInstance();
        System.out.println(clazz2.hashCode());
        System.out.println(object2);
        System.out.println("-----------------------------------");

        MyTest12  myTest123 = new MyTest12("loader3");
        myTest123.setPath("E:\\");
        Class<?> clazz3 = myTest123.loadClass("com.tianzehua.jvm.classloader.MyTest1");
        Object object3 = clazz3.newInstance();
        System.out.println(clazz3.hashCode());
        System.out.println(object3);
    }

}
